package com.sqly.doc.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
 * 时间工具类
 * @Package cn.eninesoft.util.date
 * @ClassName:DateConvert
 * @author 刘晓冰
 * @date 2015年5月13日 上午11:56:37 
 * @version V1.0
 */
public class DateConvert {
	
	public static final String YMD = "yyyy-MM-dd";
	public static final String YMDH = "yyyy-MM-dd HH";
	public static final String YMDHM = "yyyy-MM-dd HH:mm";
	public static final String YMDHMS = "yyyy-MM-dd HH:mm:ss";
	
	public static final String YMDNOSPLIT = "yyyyMMdd";
	public static final String YMDHMSNOSPLIT = "yyyyMMddHHmmss";

	/**
	 * 取得本周日期范围（周一至周日）
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static String [] currenWeekRange(){
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String startTime = "";
		String endTime = "";
		try {
			if(date.getDay()==1){
				startTime = sdf.format(date);
				endTime = sdf.format(new Date(date.getTime()+6*24*60*60*1000L));
			}else if(date.getDay()==2){
				startTime = sdf.format(new Date(date.getTime()-1*24*60*60*1000L));
				endTime = sdf.format(new Date(date.getTime()+5*24*60*60*1000L));
			}else if(date.getDay()==3){
				startTime = sdf.format(new Date(date.getTime()-2*24*60*60*1000L));
				endTime = sdf.format(new Date(date.getTime()+4*24*60*60*1000L));
			}else if(date.getDay()==4){
				startTime = sdf.format(new Date(date.getTime()-3*24*60*60*1000L));
				endTime = sdf.format(new Date(date.getTime()+3*24*60*60*1000L));
			}else if(date.getDay()==5){
				startTime = sdf.format(new Date(date.getTime()-4*24*60*60*1000L));
				endTime = sdf.format(new Date(date.getTime()+2*24*60*60*1000L));
			}else if(date.getDay()==6){
				startTime = sdf.format(new Date(date.getTime()-5*24*60*60*1000L));
				endTime = sdf.format(new Date(date.getTime()+1*24*60*60*1000L));
			}else if(date.getDay()==0){
				startTime = sdf.format(new Date(date.getTime()-6*24*60*60*1000L));
				endTime = sdf.format(date);
			}

		} catch (Exception e) {
			new Exception("取得本周日期范围（周一至周日）时出错");
		}
		return new String[]{startTime,endTime};
	}
	/**

	 * 获取当前时间字符串

	 * String dateString 时间字符串

	 * String formt 时间格式

	 * @return java.util.Date

	 */
	public static String getDateString(String formtStyle){
		try {
			SimpleDateFormat formatter = new SimpleDateFormat(formtStyle);
			return formatter.format(new Date());
		} catch (Exception e) {
			new Exception("获取当前时间字符串时出错");
			return "";
		}

	}

	/**

	 * 根据时间字符串获取时间

	 * String dateString 时间字符串

	 * String formt 时间格式

	 * @return java.util.Date

	 */
	public static Date toDate(String dateString, String formt) {
		if (dateString == null || "".equals(dateString))
			return null;
		SimpleDateFormat formatter = new SimpleDateFormat(formt);
		try {
			return formatter.parse(dateString);
		} catch (ParseException e) {
			return java.sql.Date.valueOf(dateString);
		}
	}

	/**

	 * 根据时间字符串获取时间

	 * String dateString 时间字符串

	 * String formt 时间格式

	 * @return java.sql.Date

	 */
	public static java.sql.Date toSqlDate(String dateString, String formt) {
		try {
			Date date = toDate(dateString, formt);
			if (date == null)
				return null;
			return new java.sql.Date(date.getTime());

		} catch (Exception e) {
			new Exception("根据时间字符串获取时间 (return java.sql.Date)时出错");
			return null;
		}
	}

	/**

	 * 根据时间字符串获取时间

	 * String dateString 时间字符串

	 * String formt 时间格式

	 * @return java.sql.Timestamp

	 */
	public static java.sql.Timestamp toTimestamp(String dateString, String formt) {
		try {
			Date date = toDate(dateString, formt);
			return new java.sql.Timestamp(date.getTime());

		} catch (Exception e) {
			new Exception("根据时间字符串获取时间 (return java.sql.Timestamp)时出错");
			return null;
		}
	}

	/**

	 * 根据日期获取时间字符串

	 * String java.util.Date time 日期类型

	 * String patten 时间格式

	 * @return String

	 */
	public static String dateToString(Date time, String patten) {
		if (time == null)
			return "";
		try {
			SimpleDateFormat formatter = new SimpleDateFormat(patten);
			String dateString = formatter.format(time);
			return dateString;
		} catch (Exception e) {
			new Exception("根据日期(java.util.Date)获取时间字符串时出错");
			return "";
		}
		
	}
	
	/**

	 * 根据日期获取时间字符串

	 * String java.sql.Date time 日期类型

	 * String patten 时间格式

	 * @return String

	 */
	public static String dateToString(java.sql.Date time, String patten) {
		if (time == null)
			return "";
		try {
			SimpleDateFormat formatter = new SimpleDateFormat(patten);
			String dateString = formatter.format(time);
			return dateString;
		} catch (Exception e) {
			new Exception("根据日期(java.sql.Date time)获取时间字符串时出错");
			return "";
		}
		
		
	}
	/**

	 * 根据日期获取时间字符串

	 * String java.sql.Timestamp time 日期类型

	 * String patten 时间格式

	 * @return String

	 */
	public static String dateToString(java.sql.Timestamp time, String patten) {
		if (time == null)
			return "";
		try {
			SimpleDateFormat formatter = new SimpleDateFormat(patten);
			String dateString = formatter.format(time);
			return dateString;
		} catch (Exception e) {
			new Exception("根据日期(java.sql.Timestamp time)获取时间字符串时出错");
			return "";
		}
	}
	
	/**

	 * 返回 yyyy-MM-dd 格式

	 * @param  year 年份

	 * @param  month 月分

	 * @param  day 几日

	 * @return java.util.Date

	 */
	public static Date toDate(int year, int month, int day) {
		try {
			month = month - 1;
			Calendar calendar = Calendar.getInstance();
			calendar.set(Calendar.YEAR, year);
			calendar.set(Calendar.MONTH, month);
			calendar.set(Calendar.DAY_OF_MONTH, day);

			return calendar.getTime();
		} catch (Exception e) {
			new Exception("根据年月日返回(java.util.Date)yyyy-MM-dd格式时出错");
			return null;
		}
	}

	/**

	 * 返回 yyyy-MM-dd hh:mm:ss 格式

	 * @param year 年份

	 * @param month 月分

	 * @param day 几日

	 * @param hour 几时

	 * @param minute 几分

	 * @return java.util.Date

	 */
	public static Date toDate(int year, int month, int day, int hour, int minute) {
		try {
			month = month - 1;
			Calendar calendar = Calendar.getInstance();
			calendar.set(Calendar.YEAR, year);
			calendar.set(Calendar.MONTH, month);
			calendar.set(Calendar.DAY_OF_MONTH, day);
			calendar.set(Calendar.HOUR_OF_DAY, hour);
			calendar.set(Calendar.MINUTE, minute);
			return calendar.getTime();
		} catch (Exception e) {
			new Exception("根据年月日时分秒返回(java.util.Date)yyyy-MM-dd hh:mm:ss格式时出错");
			return null;
		}
	}

	/**

	 * 返回 yyyy-MM-dd 格式

	 * @param  year

	 * @param  month

	 * @param  day

	 * @return java.sql.Date

	 */
	public static java.sql.Date toSqlDate(int year, int month, int day) {
		try {
			Date time = toDate(year, month, day);
			return new java.sql.Date(time.getTime());
		} catch (Exception e) {
			new Exception("根据年月日时分秒返回 (java.sql.Date)yyyy-MM-dd格式时出错");
			return null;
		}
	}

	/**

	 * 获得日期所在周第一天

	 * @param date 传入时间

	 * @return java.util.Date 返回时间

	 */
	public static Date getFirstDayOfWeek(Date date) {
		try {
			Calendar c = new GregorianCalendar();
			c.setFirstDayOfWeek(Calendar.MONDAY);
			c.setTime(date);
			c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
			return c.getTime();
		} catch (Exception e) {
			new Exception("获得日期所在周第一天时出错");
			return null;
		}
	}

	/**

	 * 获得当前星期几

	 * @return int day

	 */
	public static int dayofweek(){
		try {
			Calendar ca = Calendar.getInstance();
		    int day = ca.get(Calendar.DAY_OF_WEEK);
		    return day;
		} catch (Exception e) {
			new Exception("获得当前星期几时出错");
			return 0;
		}
	}

	/**

	 * 获得当前时间的时分

	 * @return int hour

	 */
	@SuppressWarnings("deprecation")
	public static int hourofday(){
		try {
			Calendar ca = Calendar.getInstance();
		    int hour = ca.getTime().getHours();
		    return hour;
		} catch (Exception e) {
			new Exception("获得当前时间的时分时出错");
			return 0;
		}
	}


	/**

	 * 获得当前时间的年分

	 * @return int hour

	 */
	public static int yearofday(){
		try {
			Calendar now = Calendar.getInstance();
		    int year =  now.get(Calendar.YEAR);
		    return year;
		} catch (Exception e) {
			new Exception("获得当前时间的年份出错");
			return 0;
		}
	}

	/**

	 * 根据时间得到昨天的时间

	 * @param date 传入时间

	 * @return String dateString 返回昨天时间

	 */
	@SuppressWarnings("deprecation")
	public static String getYesterday(Date date){
		if(date==null)return "";
		try {
			date.setDate(date.getDate()-1);
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
			String dateString = formatter.format(date);
			return dateString;
		} catch (Exception e) {
			new Exception("根据时间得到昨天的时间时出错");
			return "";
		}
	}

	/**

	 * 返回某年某月某日是星期几(汉语数字)

	 * @param date 传入时间

	 * @return String dateString  yyyy-MM-dd HH:mm:ss

	 */
	public static String WeekFormatCNString(Date date) {
		try {
			String[] weekCodes = new String[] {"日",  "一", "二", "三", "四", "五", "六",};
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			String dateString= weekCodes[calendar.get(Calendar.DAY_OF_WEEK)-1];
			return dateString;
		} catch (Exception e) {
			new Exception("返回某年某月某日是星期几(汉语数字)时出错");
			return "";
		}
	}

	/**

	 * 返回某年某月某日是星期几(阿拉伯数字)

	 * @param date 传入时间

	 * @return String dateString  yyyy-MM-dd HH:mm:ss

	 */
	public static String WeekFormatENString(Date date) {
		try {
			String[] weekCodes = new String[] {"7",  "1", "2", "3", "4", "5", "6",};
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			String dateString= weekCodes[calendar.get(Calendar.DAY_OF_WEEK)-1];
			return dateString;
		} catch (Exception e) {
			new Exception("返回某年某月某日是星期几(阿拉伯数字)时出错");
			return "";
		}
	}
	/**

	 * 计算两个日期之间的天数

	 * @param stdate

	 * @param   endate

	 * @return Long

	 */
	public static Long calcDays(Date stdate, Date endate) {
		if (stdate == null || endate == null) {
			return Long.valueOf(0);
		}
		try {
			long to = stdate.getTime();
			long from = endate.getTime();
			return (from - to) / (1000 * 60 * 60 * 24);
		} catch (Exception e) {
			new Exception("计算两个日期之间的天数时出错");
			return Long.valueOf(0);
		}
	}

	/**

	 * 获取某日期的后几天

	 * @param  dateString 传入日期

	 * @param  day 增加天数

	 * @return String

	 */
	public static String addDate(String dateString, int day) {
		try {
			Date date = toDate(dateString, "yyyy-MM-dd");
			Calendar c = Calendar.getInstance();
			c.setTimeInMillis(getMillis(date) + ((long) day) * 24 * 3600 * 1000);
			return DateConvert.dateToString(c.getTime(), "yyyy-MM-dd");
		} catch (Exception e) {
			new Exception("获取某日期的后几天时出错");
			return "";
		}
	}

	/**

	 * 获取某日期的前几天

	 * @param  dateString 传入日期

	 * @param  day 增加天数

	 * @return String

	 */
	public static String diffDate(String dateString, int day) {
		try {
			Date date = toDate(dateString, "yyyy-MM-dd");
			Calendar c = Calendar.getInstance();
			c.setTimeInMillis(getMillis(date) - ((long) day) * 24 * 3600 * 1000);
			return DateConvert.dateToString(c.getTime(), "yyyy-MM-dd");
		} catch (Exception e) {
			new Exception("获取某日期的后几天时出错");
			return "";
		}
	}
	/**

	 * 获取毫秒

	 * @param date

	 * @return long

	 */
	public static long getMillis(Date date) {
		try {
			Calendar c = Calendar.getInstance();
			c.setTime(date);
			return c.getTimeInMillis();
		} catch (Exception e) {
			new Exception("获取毫秒时出错");
			return Long.valueOf(0);
		}
	}

	/**

	 * 获取时间年份

	 * @param date 传入时间

	 * @return String 年份

	 */
	public static String YearFormatString(Date date) {
		try {
			if (date == null) return " 年";
			String formt = "yyyy";
			SimpleDateFormat formatter = new SimpleDateFormat(formt);
			String dateString = formatter.format(date);
			return dateString;
		} catch (Exception e) {
			new Exception("获取时间年份时出错");
			return " 年";
		}
	}

	/**

	 * 获取时间月份

	 * @param date 传入时间

	 * @return String 月份

	 */
	public static String MonthFormatString(Date date) {
		try {
			if (date == null) return " 月";
			String formt = "MM";
			SimpleDateFormat formatter = new SimpleDateFormat(formt);
			String dateString = formatter.format(date);
			return dateString;
		} catch (Exception e) {
			new Exception("获取时间月份时出错");
			return " 月";
		}
	}

	/**

	 * 获取时间日数

	 * @param date 传入时间

	 * @return String 日数

	 */
	public static String DayFormatString(Date date) {
		try {
			if (date == null) return " 日";
			String formt = "dd";
			SimpleDateFormat formatter = new SimpleDateFormat(formt);
			String dateString = formatter.format(date);
			return dateString;
		} catch (Exception e) {
			new Exception("获取时间日数时出错");
			return " 日";
		}
	}

	/**

	 * 获取时间小时数

	 * @param date 传入时间

	 * @return String 小时数

	 */
	public static String HourFormatString(Date date) {
		try {
			if (date == null) return " 时";
			String formt = "HH";
			SimpleDateFormat formatter = new SimpleDateFormat(formt);
			String dateString = formatter.format(date);
			return dateString;
		} catch (Exception e) {
			new Exception("获取时间小时数时出错");
			return " 时";
		}
	}

	public static String subMonth(String date,int month)  {
	        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
	        Date dt;
	        String reStr = "" ;
			try {
				dt = sdf.parse(date);
				Calendar rightNow = Calendar.getInstance();
		        rightNow.setTime(dt);
		        rightNow.add(Calendar.MONTH, -month);
		        Date dt1 = rightNow.getTime();
		        reStr = sdf.format(dt1);
			} catch (ParseException e) {
				e.printStackTrace();
			}

	        return reStr;
	    }
	/**

	 * 获取时间分钟数

	 * @param date 传入时间

	 * @return String 分钟数

	 */
	public static String MinuteFormatString(Date date) {
		try {
			if (date == null) return " 分";
			String formt = "mm";
			SimpleDateFormat formatter = new SimpleDateFormat(formt);
			String dateString = formatter.format(date);
			return dateString;
		} catch (Exception e) {
			new Exception("获取时间分钟数时出错");
			return " 分";
		}
	}

	/**

	 * 用于计算某时间所在月第一天

	 * @param date ：某时间

	 * @return

	 */
	public static Date getMonthFirstDay (Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1); // M月置1

        return calendar.getTime();
    }

	/**

	 * 用于计算某时间所在月最后一天

	 * @param date ：某时间

	 * @return

	 */
	public static Date getMonthLastDay (Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
        //获取某月最大天数

        int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最大天数

        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        return calendar.getTime();
    }

	/***

	 * 计算两个日期之间相差的天数

	 * @param smdate 较小的时间

	 * @param bdate 较大的时间

	 * @return

	 * @throws ParseException

	 */
	public static int daysBetween(String smdate,String bdate) throws ParseException{
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

       return Integer.parseInt(String.valueOf(between_days));
    }

	/***

	 * 计算两个日期之间相差的天数

	 * @param smdate 较小的时间

	 * @param bdate 较大的时间

	 * @return

	 * @throws ParseException

	 */
	public static int yearsBetween(Date smdate,Date bdate) throws ParseException{
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");

        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        int year1 = cal.get(Calendar.YEAR);
        cal.setTime(bdate);
        int year2 = cal.get(Calendar.YEAR);
            
       return year2-year1;     
    }

    public static String getCustomDatePickerNowRq(){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.CHINA);
		return sdf.format(new Date());
	}
	public static String getCustomDatePickerEndRq(){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.CHINA);
		return sdf.format(DateConvert.toDate(DateConvert.yearofday()+1,12, 31));
	}
	public static String getCustomDatePickerStartRq(){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.CHINA);
		return sdf.format(DateConvert.toDate(DateConvert.yearofday(),1, 1));
	}

	public static String getCustomDatePickerLastRq(){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.CHINA);
		return sdf.format(DateConvert.toDate(DateConvert.yearofday(),12, 31));
	}

	public static void main(String[] args) {
		//System.out.println(DateConvert.dateToString(new Date(), DateConvert.YMDNOSPLIT));
		
		
		try {
			System.out.println(DateConvert.yearsBetween(DateConvert.toDate("2009-01-01", "yyyy-MM-dd"), DateConvert.toDate("2017-03-31", "yyyy-MM-dd")));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}